home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / hard / hack / eprommerv2.lha / EPROMmer / eprommer.c < prev    next >
C/C++ Source or Header  |  1992-02-03  |  15KB  |  705 lines

  1. /*
  2.  * An adaption of EPROMmer.bas
  3.  * By Udi Finkelstein (C) 1990
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdarg.h>
  8. #include "req/reqbase.h"
  9. #include "req/req_protos.h"
  10. #include "req/req.h"
  11.  
  12. /*
  13.  * So PowerWindows doesn't add a 'chip' keyword?? so what ...
  14.  */
  15. #define USHORTTMP USHORT
  16. #undef USHORT
  17. #define USHORT USHORTTMP chip
  18. #include "EPROMmer.h"
  19. #undef USHORT
  20. #define USHORT USHORTTMP
  21.  
  22. /*
  23.  * Since I have blown PA0 on my machine, I have used one of the RS232
  24.  * signals instead, and used a 1489 receiver on the circuit instead of
  25.  * using PA0.
  26.  */
  27. #ifdef USE_RS232
  28. #define OE 0x41
  29. #else
  30. #define OE 0x01
  31. #endif
  32.  
  33. #define PGM 0x02
  34.  
  35. #define VOLTS12 (223 - 128)
  36. #define VOLTS21 (223 - 64)
  37. #define VOLTS25 (223 - 192)
  38.  
  39. /* PA2 = SEL  */
  40. #define Clock0 0
  41. #define Clock1 4
  42.  
  43. unsigned char far EmemBase[0x10000];
  44. char *EmemTop,*RamBot;
  45. volatile unsigned char *ParPort = (volatile unsigned char *)0xbfe101;
  46. volatile unsigned char *ParDDR = (volatile unsigned char *)0xbfe301;
  47. volatile unsigned char *CtrlPort = (volatile unsigned char *)0xbfd000;
  48. volatile unsigned char *CtrlDDR = (volatile unsigned char *)0xbfd200;
  49. char *EpromType;
  50.  
  51. unsigned char volt_tbl[] = { VOLTS25, VOLTS25, VOLTS21, VOLTS21,
  52.     VOLTS12, VOLTS12, VOLTS12, VOLTS12, VOLTS12 };
  53.  
  54. /* PA0 = /OE, PA1 = /PGM */
  55. unsigned char rp_tbl[] = { 0, 0, 0, PGM, PGM, PGM, 0, 0, 0 };
  56. unsigned char wp_tbl[] = { OE+PGM, OE, OE, OE, OE, OE, OE, OE, OE };
  57. unsigned char lp_tbl[] = { OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
  58.     OE+PGM, OE+PGM, OE+PGM, OE+PGM };
  59. unsigned char ip_tbl[] = { OE, OE+PGM, OE+PGM, OE+PGM, OE+PGM, OE+PGM,
  60.     OE+PGM, OE+PGM, OE+PGM };
  61. unsigned char e_flag[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0 };
  62.  
  63. unsigned short ad_tbl[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x8000 };
  64.  
  65. short Wr50ms(unsigned char), WrIntel(unsigned char), WrFast(unsigned char),
  66.     WrEprommer(unsigned char);
  67.  
  68. struct Gadget *ag_tbl[] = { &FiftyMSGad, &FiftyMSGad, &FiftyMSGad,
  69.     &IntelGad, &IntelGad, &IntelGad, &IntelGad, &IntelGad, &FastGad };
  70. short (*wa_tbl2[])(unsigned char) = { Wr50ms, WrIntel, WrEprommer, WrFast };
  71.  
  72. short (*WriteAlg)(unsigned char);
  73.  
  74. long size_tbl[] = { 2048, 4096, 4096, 8192, 8192, 16384, 32768, 65536, 32768 };
  75.  
  76. unsigned char VoltVal, ReadParam, WriteParam, LeaveParam, InhibitParam;
  77.  
  78. unsigned char Addr0, Addr1, Addr2, Addr3;
  79. unsigned char Write1, Write2, Write3, Write4, Write5;
  80. unsigned char Read0, Read1;
  81.  
  82. unsigned short LastAddr, AdParam;
  83.  
  84. LONG *RAMValInt, *RAMLowInt, *EPROMLowInt, *LengthInt;
  85.  
  86. struct Window *win;
  87. struct RastPort *rp;
  88. struct IntuitionBase *IntuitionBase;
  89. struct GfxBase *GfxBase;
  90. struct Library *ReqBase;
  91. struct Gadget *ia, *old_type_gad, *old_alg_gad;
  92. struct IntuiMessage *m;
  93. struct MsgPort *tp;
  94. struct timerequest *tr;
  95. ULONG mc;
  96. long Size;
  97. short EPType = -1;
  98.  
  99. char Dir[DSIZE + 1], File[FCHARS + 1], FullPath[DSIZE+FCHARS+2];
  100. struct ReqFileRequester frq ;
  101.  
  102. void UpdateLongInt(g)
  103. struct Gadget *g;
  104. {
  105. SHORT pos;
  106. struct StringInfo *si;
  107.  
  108.     si = (struct StringInfo *)(g->SpecialInfo);
  109.     pos = RemoveGList(win, g, 1);
  110.     sprintf(si->Buffer, "%lu", si->LongInt);
  111.     si->NumChars = strlen(si->Buffer);
  112.     AddGList(win, g, pos, 1, NULL);
  113.     RefreshGList(g, win, NULL, 1);
  114. }
  115.  
  116. /*
  117.  * Turn off the previously selected gadget, if there was one.
  118.  */
  119. void GadExclude(gad)
  120. struct Gadget *gad;
  121. {
  122.     if (gad) {
  123. /* Turn off previous gadget */
  124.         gad->Flags ^= SELECTED;
  125.         SetAPen(rp, 0);
  126.         SetDrMd(rp, JAM1);
  127.         RectFill(rp, gad->LeftEdge, gad->TopEdge,
  128.             gad->LeftEdge + gad->Width, gad->TopEdge + gad->Height);
  129.         RefreshGList(gad, win, NULL, 1);
  130.     }
  131. }
  132.  
  133. /*
  134.  * A general one gadget requester using req.library
  135.  */
  136. void SimpleRequest(char *str,...)
  137. {
  138. va_list ap;
  139. struct TRStructure trs;
  140.  
  141.     va_start(ap,str);
  142.  
  143.     trs.Text = str;
  144.     trs.Controls = ap;
  145.     trs.Window = 0;
  146.     trs.MiddleText = 0;
  147.     trs.PositiveText = 0;
  148.     trs.NegativeText = "Resume";
  149.     trs.Title = "Ahem...";
  150.     trs.KeyMask = 0xFFFF;
  151.     trs.textcolor = 1;
  152.     trs.detailcolor = 2;
  153.     trs.blockcolor = 3;
  154.     trs.versionnumber = REQVERSION;
  155.     trs.Timeout = 0;
  156.     trs.AbortMask = 0;
  157.     trs.rfu1 = 0;
  158.  
  159.     TextRequest(&trs);
  160.     va_end(ap);
  161. }
  162.  
  163. /*
  164.  * A general two gadget requester using req.library
  165.  */
  166. short TwoGadRequest(char *str,...)
  167. {
  168. va_list ap;
  169. struct TRStructure trs;
  170. short res;
  171.  
  172.     va_start(ap,str);
  173.  
  174.     trs.Text = str;
  175.     trs.Controls = ap;
  176.     trs.Window = 0;
  177.     trs.MiddleText = 0;
  178.     trs.PositiveText = "  OK  ";
  179.     trs.NegativeText = "CANCEL";
  180.     trs.Title = "Ahem...";
  181.     trs.KeyMask = 0xFFFF;
  182.     trs.textcolor = 1;
  183.     trs.detailcolor = 2;
  184.     trs.blockcolor = 3;
  185.     trs.versionnumber = REQVERSION;
  186.     trs.Timeout = 0;
  187.     trs.AbortMask = 0;
  188.     trs.rfu1 = 0;
  189.  
  190.     res = TextRequest(&trs);
  191.     va_end(ap);
  192.     return(res);
  193. }
  194.  
  195. /*
  196.  * Timer initialization done here
  197.  */
  198. short OpenTimer()
  199. {
  200.  
  201.     if ((tp = CreatePort(0, 0)) == 0) return 1;
  202.     if ((tr = (struct timerequest *)CreateExtIO(tp, sizeof(struct timerequest)))
  203.         == NULL) return 1;
  204.  
  205.     if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0))
  206.         return 1;
  207. }
  208.  
  209. /*
  210.  * Timer cleanup done here
  211.  */
  212. void CloseTimer(tr)
  213. struct timerequest *tr;
  214. {
  215.  
  216.     if (tp) DeletePort(tp);
  217.     if (tr) {
  218.         CloseDevice((struct IORequest *)tr);
  219.         DeleteExtIO((struct IORequest *)tr);
  220.     }
  221. }
  222.  
  223. /*
  224.  * A MicroHz precision delay routine
  225.  */
  226. void uDelay(delay)
  227. unsigned long delay;
  228. {
  229.  
  230.     tr->tr_node.io_Command = TR_ADDREQUEST;
  231.     tr->tr_time.tv_secs = 0;
  232.     tr->tr_time.tv_micro = delay;
  233.     DoIO((struct IORequest *)tr);
  234. }
  235.  
  236. void SetAddr(Address)
  237. unsigned short Address;
  238. {
  239.  
  240.     LastAddr = Address;
  241.     *ParDDR = 255;
  242.     *ParPort = 253;
  243.     *CtrlPort = Addr0;
  244.     *ParPort = Address >> 8;
  245.     *CtrlPort = Addr1;
  246.     *ParPort = 254;
  247.     *CtrlPort = Addr2;
  248.     *ParPort = Address & 255;
  249.     *CtrlPort = Addr3;
  250. }
  251.  
  252. void InitPorts()
  253. {
  254.  
  255.     *CtrlDDR = Clock1 + OE + PGM;
  256.     *CtrlPort = Clock0 + OE + PGM;
  257.     *ParDDR = 255;
  258.     *ParPort = 255;
  259.     *CtrlPort = Clock1 + OE + PGM;
  260.     *CtrlPort = Clock0 + OE + PGM;;
  261.  
  262.     SetAddr(0);
  263. }
  264.  
  265. void VPP_on()
  266. {
  267.     *ParDDR = 255;
  268.     *ParPort = VoltVal;
  269.     *CtrlPort = Clock1;
  270. }
  271.  
  272. void VPP_off()
  273. {
  274.     *ParPort = 255;
  275.     *CtrlPort = LeaveParam + Clock0;
  276.     *CtrlPort = LeaveParam + Clock1;
  277.     *CtrlPort = LeaveParam + Clock0;
  278. }
  279.  
  280. void ThatsIt()
  281. {
  282.     SetAddr(0);
  283.     *CtrlDDR = 0;
  284.     *ParDDR = 0;
  285. }
  286.  
  287. unsigned char ReadByte()
  288. {
  289. unsigned char DataIn;
  290.  
  291. /* If A15 is used for /WR, make sure it's high now - used for 62256 */
  292.     if (AdParam & 0x8000 & ~LastAddr) SetAddr(LastAddr | 0x8000);
  293. /* port is now input */
  294.     *ParDDR = 0;
  295.     *CtrlPort = Read0;
  296.     DataIn = *ParPort;
  297.     *CtrlPort = Read1;
  298.     return DataIn;
  299. }
  300.  
  301. void WriteByte(DataOut, delay)
  302. unsigned char DataOut;
  303. unsigned long delay;
  304. {
  305. /* If A15 is used for /WR, make sure it's low now - used for 62256 */
  306.     if (AdParam & 0x8000 & LastAddr) SetAddr(LastAddr & 0x7fff);
  307.     *ParDDR = 255;
  308.     *ParPort = VoltVal;
  309.     *CtrlPort = Write1;
  310.     *ParPort = DataOut;
  311.     *CtrlPort = Write2;
  312.     uDelay(delay);
  313.     *CtrlPort = Write3;
  314.     *ParPort = 255;
  315.     *CtrlPort = Write4;
  316.     *CtrlPort = Write5;
  317. }
  318.  
  319. void SetCycleParams()
  320. {
  321.     Write1 = InhibitParam + Clock1;
  322.     Write2 = WriteParam + Clock1;
  323.     Write3 = InhibitParam + Clock0;
  324.     Write4 = InhibitParam + Clock1;
  325.     Write5 = LeaveParam + Clock0;
  326.     Read0 = ReadParam + Clock0;
  327.     Read1 = LeaveParam + Clock0;
  328.     Addr0 = LeaveParam + Clock1;
  329.     Addr1 = LeaveParam + Clock0;
  330.     Addr2 = LeaveParam + Clock1;
  331.     Addr3 = LeaveParam + Clock0;
  332. }
  333.  
  334. /*
  335.  * Write a single byte
  336.  */
  337. short WriteCycle(DataOut)
  338. unsigned char DataOut;
  339. {
  340. unsigned char c;
  341.  
  342. /* Any bit set in DataOut which is already reset in the EPROM? */
  343.     c = ReadByte();
  344.     if (e_flag[EPType] && (~c & DataOut)) return 1;
  345.  
  346. /* Is data already identical? */
  347.     if (DataOut == c) return 0;
  348.  
  349.     return (*WriteAlg)(DataOut);
  350. }
  351.  
  352. /*
  353.  * The Eprommer algorythm - a variation on the intel algorythm.
  354.  */
  355. short WrEprommer(DataOut)
  356. unsigned char DataOut;
  357. {
  358. short n;
  359. unsigned long l;
  360.  
  361. /* Programming loop */
  362.     n = 0;
  363.     while(++n < 20) {
  364.         WriteByte(DataOut, 1000);
  365.         if (ReadByte() == DataOut) {
  366. /* Overprogramming section */
  367.             l = n * 5000;
  368.             if (l > 20000) l = 20000;
  369.             WriteByte(DataOut, l);
  370.             return 0;
  371.         }
  372.     }
  373. /* Too many retries, must be EPROM failure */
  374.     return 2;
  375. }
  376.  
  377. /*
  378.  * The IntEligent programming algorythm algorythm.
  379.  */
  380. short WrIntel(DataOut)
  381. unsigned char DataOut;
  382. {
  383. short n;
  384.  
  385. /* Programming loop */
  386.     n = 0;
  387.     while(++n < 15) {
  388.         WriteByte(DataOut, 1000);
  389.         if (ReadByte() == DataOut) {
  390. /* Overprogramming section */
  391.             WriteByte(DataOut, n * 4000);
  392.             return 0;
  393.         }
  394.     }
  395. /* Too many retries, must be EPROM failure */
  396.     return 2;
  397. }
  398.  
  399. /*
  400.  * The fastest algorythm - use for RAMs only!
  401.  */
  402. short WrFast(DataOut)
  403. unsigned char DataOut;
  404. {
  405. /* No loop! */
  406.     WriteByte(DataOut, 10);
  407.     if (ReadByte() == DataOut) return 0;
  408.  
  409. /* RAM failure */
  410.     return 2;
  411. }
  412.  
  413. /*
  414.  * The basic 50ms pulse algorythm.
  415.  * Use for 2716, 2732 and 2732A chips which requires it. not all
  416.  * brands of chips require this slow algorythm (Intel does, TI don't).
  417.  */
  418. short Wr50ms(DataOut)
  419. unsigned char DataOut;
  420. {
  421. /* No loop! */
  422.     WriteByte(DataOut, 50000);
  423.     if (ReadByte() == DataOut) return 0;
  424.  
  425. /* RAM failure */
  426.     return 2;
  427. }
  428.  
  429. /*
  430.  * Read a file into the buffer
  431.  */
  432. void LoadFile()
  433. {
  434. FILE *fin;
  435.  
  436.     frq.VersionNumber = REQVERSION;
  437.     frq.Dir = Dir;
  438.     frq.File = File;
  439.     frq.PathName = FullPath;
  440.     frq.Title = "Buffer Load";
  441.     frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
  442.  
  443.     if (!FileRequester(&frq)) return;
  444.  
  445.     if ((fin = fopen(FullPath, "r")) == NULL) {
  446.         SimpleRequest("Could not open input file (%s)!", FullPath);
  447.         return;
  448.     }
  449.     *LengthInt = fread(EmemBase + *RAMLowInt, 1, 0x10000 - *RAMLowInt, fin);
  450.     SimpleRequest("We read %ld bytes", *LengthInt);
  451.     UpdateLongInt(&Length);
  452.     fclose(fin);
  453. }
  454.  
  455. /*
  456.  * Save a part of the buffer to disk
  457.  */
  458. void SaveFile()
  459. {
  460. FILE *fin;
  461. LONG len;
  462.  
  463.     frq.VersionNumber = REQVERSION;
  464.     frq.Dir = Dir;
  465.     frq.File = File;
  466.     frq.PathName = FullPath;
  467.     frq.Title = "Buffer Save";
  468.     frq.Flags = FRQCACHINGM|FRQLOADINGM|FRQHIDEWILDSM;
  469.  
  470.     if (!FileRequester(&frq)) return;
  471.  
  472.     if ((fin = fopen(FullPath, "w")) == NULL) {
  473.         SimpleRequest("Could not open output file!");
  474.         return;
  475.     }
  476.     len = fwrite(EmemBase + *RAMLowInt, 1, *LengthInt, fin);
  477.     if (len == *LengthInt)
  478.         SimpleRequest("We wrote %ld bytes", len);
  479.     else
  480.         SimpleRequest("We wrote only %ld bytes Instead of %ld bytes",
  481.             len, *LengthInt);
  482.     fclose(fin);
  483. }
  484.  
  485. /*
  486.  * Read the EPROM
  487.  */
  488. void ReadEPROM()
  489. {
  490. unsigned short addr, len;
  491. unsigned char *c;
  492.  
  493.     if (EPType == -1) {
  494.         SimpleRequest("You must select an EPROM type first!");
  495.         return;
  496.     }
  497.     len = *LengthInt;
  498.     addr = *EPROMLowInt;
  499.     c = &EmemBase[*RAMLowInt];
  500.     while (len--) {
  501.         SetAddr(addr++);
  502.         *c++ = ReadByte();
  503.     }
  504.     SimpleRequest("We read %ld bytes", *LengthInt);
  505. }
  506.  
  507. /*
  508.  * Compare the EPROM with the RAM buffer
  509.  */
  510. void CompareEPROM()
  511. {
  512. unsigned short addr, len;
  513. unsigned char *c, ce, cr;
  514.  
  515.     if (EPType == -1) {
  516.         SimpleRequest("You must select an EPROM type first!");
  517.         return;
  518.     }
  519.     len = *LengthInt;
  520.     addr = *EPROMLowInt;
  521.     c = &EmemBase[*RAMLowInt];
  522.     while (len--) {
  523.         SetAddr(addr++);
  524.         if ((cr = *c++) != (ce = ReadByte()))
  525.             if (!TwoGadRequest("Offset %ld, EPROM:%02lx   RAM:%02lx",
  526.                 addr - *EPROMLowInt - 1, ce, cr)) return;
  527.     }
  528.     SimpleRequest("We compared %ld bytes", *LengthInt);
  529. }
  530.  
  531. /*
  532.  * Make sure EPROM is empty
  533.  */
  534. void CheckEPROM()
  535. {
  536. unsigned long addr;
  537.  
  538.     if (EPType == -1) {
  539.         SimpleRequest("You must select an EPROM type first!");
  540.         return;
  541.     }
  542.     for (addr = 0; addr < Size;) {
  543.         SetAddr((unsigned short)(addr++));
  544.         if (ReadByte() != 255) {
  545.             SimpleRequest("EPROM contains data at %ld!", addr - 1);
  546.             return;
  547.         }
  548.     }
  549.     SimpleRequest("EPROM is empty");
  550. }
  551.  
  552. /*
  553.  * Program the EPROM
  554.  */
  555. void ProgramEPROM()
  556. {
  557. unsigned short addr, len;
  558. unsigned char *c;
  559.  
  560.     if (EPType == -1) {
  561.         SimpleRequest("You must select an EPROM type first!");
  562.         return;
  563.     }
  564.     len = *LengthInt;
  565.     addr = *EPROMLowInt;
  566.     c = &EmemBase[*RAMLowInt];
  567.     while (len--) {
  568.         SetAddr(addr++);
  569.         switch (WriteCycle(*c++)) {
  570.             case 2:
  571.                 SimpleRequest("Verify error at EPROM address %d", addr - 1);
  572.                 return;
  573.  
  574.             case 1:
  575.                 SimpleRequest("EPROM already has data at address %d", addr - 1);
  576.                 return;
  577.         }
  578.     }
  579.     SimpleRequest("We programmed %ld bytes", *LengthInt);
  580. }
  581.  
  582. /*
  583.  * free every resource we might have allocated
  584.  */
  585. void cleanup(s)
  586. char *s;
  587. {
  588.     ThatsIt();
  589.     PurgeFiles(&frq);
  590.     if (s) Write(Output(), s, strlen(s));
  591.     if (tp) CloseTimer(tr);
  592.     if (win) CloseWindow(win);
  593.     if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  594.     if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  595.     if (ReqBase) CloseLibrary(ReqBase);
  596.     exit(0);
  597. }
  598.  
  599. main()
  600. {
  601.  
  602. /*
  603.  * Open all libraries, as well as the program's window
  604.  */
  605.     if (!(IntuitionBase = (struct IntuitionBase *)
  606.         OpenLibrary("intuition.library", 33L)))
  607.             cleanup("No intuition.library!\n");
  608.  
  609.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33L)))
  610.         cleanup("No graphics.library!\n");
  611.  
  612.     if (!(ReqBase = OpenLibrary("req.library", 0L)))
  613.         cleanup("No req.library!\n");
  614.  
  615.     if (!(win = OpenWindow(&NewWindowStructure1)))
  616.             cleanup("No window!\n");
  617.  
  618.     rp = win->RPort;
  619.  
  620. /* Initialization for timer */
  621.     if (OpenTimer()) cleanup("No timer!");
  622.  
  623. /*
  624.  * Warning! due to a Lattice bug, we can't initialize these variables while
  625.  * they're defined, even though it's value is known at the time. They get
  626.  * initialized, but with the wrong values. Instead, we initialize them at
  627.  * run time.
  628.  */
  629.     RAMLowInt = &(((struct StringInfo *)(RAMLow.SpecialInfo))->LongInt);
  630.     RAMValInt = &(((struct StringInfo *)(RAMVal.SpecialInfo))->LongInt);
  631.     EPROMLowInt = &(((struct StringInfo *)(EPROMLow.SpecialInfo))->LongInt);
  632.     LengthInt = &(((struct StringInfo *)(Length.SpecialInfo))->LongInt);
  633.  
  634. /* Update display */
  635.     UpdateLongInt(&RAMLow);
  636.     UpdateLongInt(&Length);
  637.     UpdateLongInt(&EPROMLow);
  638.  
  639. /* Initialize hardware */
  640.     InitPorts();
  641.  
  642. /*
  643.  * Event loop
  644.  */
  645.     while (1) {
  646.         Wait(1L << (win->UserPort->mp_SigBit));
  647.         while (m = (struct IntuiMessage *)GetMsg(win->UserPort)) {
  648.             ia = (struct Gadget *)m->IAddress;
  649.             mc = m->Class;
  650.             ReplyMsg((struct Message *)m);
  651.             if (mc == CLOSEWINDOW) {
  652.                 SimpleRequest("Please remove the EPROM now");
  653.                 cleanup(NULL);
  654.             } else if (mc == GADGETUP) {
  655.                 if (ia == &LoadGad) LoadFile();
  656.                 else if (ia == &SaveGad) SaveFile();
  657.                 else if (ia == &ReadGad) ReadEPROM();
  658.                 else if (ia == &CheckGad) CheckEPROM();
  659.                 else if (ia == &ProgramGad) ProgramEPROM();
  660.                 else if (ia == &CompareGad) CompareEPROM();
  661.                 else if (ia == &VPPGad) {
  662.                     VPP_on();
  663.                     SimpleRequest("VPP on now, press OK to turn it off");
  664.                     VPP_off();
  665.                 } else if (ia == &ReadByteGad) {
  666.                     *RAMValInt = EmemBase[*RAMLowInt];
  667.                     UpdateLongInt(&RAMVal);
  668.                 } else if (ia == &WriteByteGad) {
  669.                     EmemBase[*RAMLowInt] = (*RAMValInt &= 255);
  670.                     UpdateLongInt(&RAMVal);
  671.                 }
  672.             } else if (mc == GADGETDOWN) {
  673.                 if ((LONG)(ia->UserData) & 0x200) {
  674. /* get EPROM type */
  675.                     EPType = (unsigned char)(ia->UserData);
  676. /* set EPROM parameters */
  677.                     Size = size_tbl[EPType];
  678.                     VoltVal = volt_tbl[EPType];
  679.                     ReadParam = rp_tbl[EPType];
  680.                     WriteParam = wp_tbl[EPType];
  681.                     InhibitParam = ip_tbl[EPType];
  682.                     AdParam = ad_tbl[EPType];
  683.                     *CtrlPort = LeaveParam = lp_tbl[EPType];
  684.                     SetCycleParams();
  685. /* turn off old gad */
  686.                     GadExclude(old_type_gad);
  687.                     old_type_gad = ia;
  688. /* inform user */
  689.                     SimpleRequest("Check for correct Personality Module");
  690. /* fake a gadget event to set the defalut algorythm for the new type */
  691.                     ia = ag_tbl[EPType];
  692. /* Use GadExclude to turn the new gadget ON! */
  693.                     GadExclude(ia);
  694. /* Fall into the algorythm gadget's code to turn old gad off */
  695.                 }
  696.                 if ((LONG)(ia->UserData) & 0x100) {
  697.                     WriteAlg = wa_tbl2[(unsigned char)(ia->UserData)];
  698.                     GadExclude(old_alg_gad);
  699.                     old_alg_gad = ia;
  700.                 }
  701.              }
  702.         }
  703.     }
  704. }
  705.